package haiyan.common.security;

import java.lang.reflect.Constructor;
import java.security.SecureRandom;
import java.security.spec.KeySpec;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;

/**
 * 公钥解密数据
 * 
 * @author zhouxw
 * 
 */
public class DecryptData {

	/**
	 * 
	 */
	private String keyfile = "";

	/**
	 * @param keyfile
	 */
	public DecryptData(String keyfile) {
		this.keyfile = keyfile;
	}

	/**
	 * @param keyfile
	 *            String
	 */
	public void setKeyFile(String keyfile) {
		this.keyfile = keyfile;
	}

//	/**
//	 * @param encryptfile
//	 * @param filename
//	 * @throws Throwable
//	 */
//	public void createUnEncryptData(String filename, String encryptfile)
//			throws Throwable {
//		if (keyfile == null || keyfile.equals("")) {
//			throw new NullPointerException("...");
//		}
//		unEncryptData(filename, encryptfile);
//	}
//
//	/**
//	 * @param encryptfile
//	 * @param filename
//	 * @throws Throwable
//	 */
//	private void unEncryptData(String filename, String encryptfile)
//			throws Throwable {
//		byte[] data = DesUtil.readFile(encryptfile);
//		byte unEncryptData[] = getUnEncryptData(data);
//		DesUtil.writeFile(unEncryptData, filename);
//	}

	/**
	 * @param bytes byte[]
	 * @return byte[]
	 * @throws Throwable
	 */
	public byte[] createUnEncryptData(byte[] bytes) throws Throwable {
		bytes = getUnEncryptData(bytes);
		return bytes;
	}

	/**
	 * @param bytes byte[]
	 * @return byte[]
	 * @throws Throwable
	 */
	private byte[] getUnEncryptData(byte[] bytes) throws Throwable {
		SecretKey key = null; // 密文
		// Cipher
		Cipher cipher = null;
		if (!DesUtil.getUseRandom()) {
			key = getKeyByRawKeyData(DesUtil.getAlgorithmKey().getBytes());
			IvParameterSpec spec = new IvParameterSpec(DesUtil.iv);
			// "Rijndael/CBC/PKCS5Padding" "DES/ECB/PKCS5Padding"
			cipher = Cipher.getInstance(DesUtil.getAlgorithm());
			cipher.init(Cipher.DECRYPT_MODE, key, spec);
		} else {
			key = getKeyByRawKeyData(DesUtil.readFile(keyfile));
			SecureRandom sr = new SecureRandom();
			// Cipher
			cipher = Cipher.getInstance(DesUtil.getAlgorithm());
			cipher.init(Cipher.DECRYPT_MODE, key, sr);
		}
		bytes = cipher.doFinal(bytes);
		return bytes;
	}

	/**
	 * @param rawKeyData
	 * @return SecretKey
	 * @throws Throwable
	 */
	private SecretKey getKeyByRawKeyData(byte[] rawKeyData) throws Throwable {
		Class<?> classkeyspec = Class.forName(DesUtil.getValue("keyspec"));
		Constructor<?> constructor = classkeyspec.getConstructor(new Class[] { byte[].class });
		KeySpec dks = (KeySpec) constructor.newInstance(new Object[] { rawKeyData });
		// new DESKeySpec(rawKeyData);
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DesUtil.getAlgorithmKeyType());
		return keyFactory.generateSecret(dks);
	}

}